var Ajax = {

	TEXT:   'text',
	STREAM: 'stream',
	BYTES:  'bytes',
	XML:    'xml',
	
	ajax: function( url, callback, type ) {
		Ajax.submitRequest( 
			Ajax.getRequestFactorInstance()
			, url
			, callback
			, type 
		);
	},

	/**
	 *
	 * create an async request and dispatch the result (on success)
	 * to the callback
	 * 
	 * @param ajaxFactory
	 * @param url
	 * @param callback
	 * @param type (xml|text|bytes|stream), defaults to xml
	 *
	 */
	submitRequest: function( ajaxFactory, url, callback, type ) {
	
		var req = ajaxFactory();

		if ( 'stream' != type && 'bytes' != type && 'text' != type ) {
			req.overrideMimeType( 'text/xml' );
		}
		req.onreadystatechange = function() { 
			if ( 4 == req.readyState ) {
				if ( 200 == req.status || 0 == req.status ) {
					callback( Ajax.content( req, type ) );
				} else {
					/* TODO: add error handler */
				}
			}
		};
		req.open( 'GET', url, true );
		req.send( null );
	},

	content: function( req, type ) {
		var result = '';
		if ( 'stream' == type ) {
			 result = ( req.responseStream );
		} else
		if ( 'bytes' == type ) {
			 result = ( req.responseBody );
		} else
		if ( 'text' == type ) {
			 result = ( req.responseText );
		} else {
			 result = ( req.responseXML );
		}
		return result;
	 },
	
	/**
	 * 
	 * Find the mechanism for this browser to create 
	 * new XMLHttpRequest objects
	 * 
	 * @return a function that creates new XMLHttpRequest object
	 * 
	 */
	requestFactory: function() { 
	   try { 
		   new XMLHttpRequest(); 
		   return function() { return new XMLHttpRequest(); };
	   } catch ( e1 ) { 
		   try { 
			   window.XMLHttpRequest; 
			   return function() { return window.XMLHttpRequest; };
		   } catch ( e2 ) { 
			   try { 
				   new ActiveXObject( 'Microsoft.XMLHTTP' ); 
				   return function() { return new ActiveXObject( 'Microsoft.XMLHTTP' );  };
			   } catch ( e3 ) { 
				   try { 
					   new ActiveXObject( 'Msxml2.XMLHTTP' ) 
					   return function() { return new ActiveXObject( 'Msxml2.XMLHTTP' ); };
				   } catch ( e4 ) { 
					   return function() { return false; };
				   } 
			   } 
		   } 
	   } 
	},

	requestFactoryInstance_: Util.unset,
							 
	getRequestFactorInstance: function() {
		return (
			Ajax.requestFactoryInstance_
			? Ajax.requestFactoryInstance_	
			: Ajax.requestFactoryInstance_ = Ajax.requestFactory()
		);
	}	
};
